<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;

class BankDetailHangzhou extends Model
{
    use HasFactory;

    protected $table = 'bank_details_hangzhou';

    protected $fillable = [
        'serial_no',
        'serial_id',
        'voucher_no',
        'trans_date',
        'trans_time',
        'transaction_datetime',
        'bank_acc',
        'acc_name',
        'amt',
        'bal',
        'cd_sign',
        'cur',
        'opp_acc_name',
        'opp_acc_no',
        'opp_acc_bank',
        'bank_name',
        'abs',
        'uses',
        'match_status',
        'matched_recharge_id',
        'match_confidence',
        'matched_at',
        'matched_by',
        'sync_batch_id',
        'raw_data',
        'synced_at',
        'receipt_path',
        'receipt_retrieved_at',
    ];

    protected $casts = [
        'id' => 'string',
        'matched_recharge_id' => 'string',
        'trans_date' => 'date',
        'transaction_datetime' => 'datetime',
        'amt' => 'decimal:2',
        'bal' => 'decimal:2',
        'match_confidence' => 'decimal:2',
        'matched_at' => 'datetime',
        'synced_at' => 'datetime',
        'raw_data' => 'array',
        'receipt_retrieved_at' => 'datetime',
    ];

    /**
     * 关联到匹配的充值申请
     */
    public function recharge()
    {
        return $this->belongsTo(Recharge::class, 'matched_recharge_id');
    }

    /**
     * 关联到匹配操作的管理员
     */
    public function matchedBy()
    {
        return $this->belongsTo(AdminUser::class, 'matched_by');
    }

    /**
     * 范围：未匹配的明细
     */
    public function scopeUnmatched($query)
    {
        return $query->where('match_status', 'unmatched');
    }

    /**
     * 范围：已匹配的明细
     */
    public function scopeMatched($query)
    {
        return $query->where('match_status', 'matched');
    }

    /**
     * 范围：收入明细
     */
    public function scopeIncome($query)
    {
        return $query->where('cd_sign', '0');
    }

    /**
     * 范围：支出明细
     */
    public function scopeExpense($query)
    {
        return $query->where('cd_sign', '1');
    }

    /**
     * 范围：指定时间范围
     */
    public function scopeDateRange($query, $startDate, $endDate)
    {
        return $query->whereBetween('trans_date', [$startDate, $endDate]);
    }

    /**
     * 范围：指定金额范围
     */
    public function scopeAmountRange($query, $minAmount, $maxAmount = null)
    {
        $query->where('amt', '>=', $minAmount);
        if ($maxAmount !== null) {
            $query->where('amt', '<=', $maxAmount);
        }
        return $query;
    }

    /**
     * 从银行API响应数据创建模型实例
     *
     * @param array $apiData 银行API返回的单条明细数据
     * @param string $syncBatchId 同步批次ID
     * @return static
     */
    public static function createFromApiData(array $apiData, string $syncBatchId): self
    {
        // 解析交易时间
        $transactionDateTime = Carbon::parse($apiData['transTime'] ?? $apiData['transDate']);

        return self::create([
            'serial_no' => $apiData['serialNo'],
            'serial_id' => $apiData['serialId'] ?? '',
            'voucher_no' => $apiData['voucherNo'] ?? null,
            'trans_date' => $transactionDateTime->toDateString(),
            'trans_time' => $transactionDateTime->toTimeString(),
            'transaction_datetime' => $transactionDateTime,
            'bank_acc' => $apiData['bankAcc'],
            'acc_name' => $apiData['accName'],
            'amt' => $apiData['amt'],
            'bal' => $apiData['bal'],
            'cd_sign' => $apiData['cdSign'],
            'cur' => $apiData['cur'] ?? '人民币',
            'opp_acc_name' => $apiData['oppAccName'] ?? null,
            'opp_acc_no' => $apiData['oppAccNo'] ?? null,
            'opp_acc_bank' => $apiData['oppAccBank'] ?? null,
            'bank_name' => $apiData['bankName'] ?? null,
            'abs' => $apiData['abs'] ?? null,
            'uses' => $apiData['uses'] ?? null,
            'match_status' => 'unmatched',
            'sync_batch_id' => $syncBatchId,
            'raw_data' => $apiData,
            'synced_at' => now(),
        ]);
    }

    /**
     * 标记为已匹配
     *
     * @param int $rechargeId 充值申请ID
     * @param float $confidence 匹配置信度
     * @param int|null $matchedBy 匹配操作人ID
     * @return bool
     */
    public function markAsMatched(int $rechargeId, float $confidence, int $matchedBy = null): bool
    {
        return $this->update([
            'match_status' => 'matched',
            'matched_recharge_id' => $rechargeId,
            'match_confidence' => $confidence,
            'matched_at' => now(),
            'matched_by' => $matchedBy,
        ]);
    }

    /**
     * 标记为忽略
     *
     * @param int|null $operatorId 操作人ID
     * @return bool
     */
    public function markAsIgnored(int $operatorId = null): bool
    {
        return $this->update([
            'match_status' => 'ignored',
            'matched_by' => $operatorId,
            'matched_at' => now(),
        ]);
    }

    /**
     * 取消匹配
     *
     * @return bool
     */
    public function unmatch(): bool
    {
        return $this->update([
            'match_status' => 'unmatched',
            'matched_recharge_id' => null,
            'match_confidence' => 0.00,
            'matched_at' => null,
            'matched_by' => null,
        ]);
    }

    /**
     * 格式化显示金额
     *
     * @return string
     */
    public function getFormattedAmountAttribute(): string
    {
        return number_format($this->amt, 2);
    }

    /**
     * 格式化显示余额
     *
     * @return string
     */
    public function getFormattedBalanceAttribute(): string
    {
        return number_format($this->bal, 2);
    }

    /**
     * 获取收支类型文字
     *
     * @return string
     */
    public function getTransactionTypeAttribute(): string
    {
        return $this->cd_sign === '0' ? '收入' : '支出';
    }

    /**
     * 获取匹配状态文字
     *
     * @return string
     */
    public function getMatchStatusTextAttribute(): string
    {
        switch ($this->match_status) {
            case 'unmatched':
                return '未匹配';
            case 'matched':
                return '已匹配';
            case 'ignored':
                return '已忽略';
            default:
                return '未知';
        }
    }
}
